import axios from '@/utils/_require'
import axiosOld from 'axios';
import _ from 'lodash';


export class Operation {
  constructor(data) {
    Object.assign(this, data)
    if (!this.controller) this.controller = new AbortController()
  }
  type = ''
  method = ''
  params = {}
  data = null
  error = null
  controller = null
  pageInfo = {}
}

// Axios代理器
export class AxiosProxy {
  actions = null
  /**
    actions: {
        read: {
          url: option.requestAddress,
          method: 'get'
        },
        delete: {
          url: option.requestAddress,
          method: 'delete'
        },
        create: {
          url: option.requestAddress,
          method: 'post'
        },
        update: {
          url: option.requestAddress,
          method: 'put'
        },
      }
   */
  constructor(option) {
    Object.assign(this, option)
  }

  // 状态访问器
  getSuccess(responseData) {
    return responseData.data.code == 200
  }

  // 结果根访问器
  getRoot(responseData) {
    return responseData.data.data?.records
  }


  getPageInfo(responseData, operation) {
    return {
      page: responseData.data.data.current || 1,
      pageSize: responseData.data.data.size || 10,
      count: responseData.data.data.total || 0
    }
  }

  // axios配置访问器
  getAxiosConfig(operation) {
    // operation = { type:'create || read || update || delete', method: ' post || get || put || delete' }
    // 读 read-get、 删除 delete-delete 是简单请求
    const config = {
      params: {},
      data: {}
    }

    // 处理请求 url 和 method 
    if (operation.type === 'read') {
      Object.assign(config, {
        url: _.template(this.actions.read.url)({
          ...operation?.option,
          ...operation?.params,
        }),
        method: this.actions.read.method
      })
    } else if (operation.type === 'update') {
      Object.assign(config, {
        url: _.template(this.actions.update.url)({
          ...operation?.option,
          ...operation?.data,
        }),
        method: this.actions.update.method
      })
    } else if (operation.type === 'delete') {
      Object.assign(config, {
        url: _.template(this.actions.delete.url)({
          ...operation?.option,
          ...operation?.params,
        }),
        method: this.actions.delete.method
      })
    } else if (operation.type === 'create') {
      Object.assign(config, {
        url: _.template(this.actions.create.url)({
          ...operation?.option,
          ...operation?.data,
        }),
        method: this.actions.create.method
      })
    }

    // 处理取消请求控制器
    if (operation.controller) {
      config.signal = operation.controller.signal
    }

    // 处理 请求参数
    if (config.method === 'get' || config.method === 'delete') {
      Object.assign(config.params, operation.params)
    } else if (config.method === 'put' || config.method === 'post') {
      Object.assign(config.data, operation.data)
    }

    return config
  }

  // 执行器
  async execute(operation) {
    try {
      // 获取请求的配置config
      const config = this.getAxiosConfig(operation)

      // 发送请求
      const responseData = await axios({
        ...config
      })

      // 判定是否为成功
      if (this.getSuccess(responseData)) {
        let root = this.getRoot(responseData)

        if (Array.isArray(root)) {
          Object.assign(operation.pageInfo, this.getPageInfo(responseData))
        }

        // 返回结果
        Object.assign(operation, {
          status: 2,
          data: this.getRoot(responseData)
        })


      } else {
        // 不成功
        throw new Error(responseData?.message || '解析错误')
      }
    } catch (e) {
      console.log(e)
      // 返回不超过结果
      Object.assign(operation, {
        status: axiosOld.isCancel(e) ? 4 : 3,
        error: e.message || 'error',
        data: null
      })
    }
  }
}